package com.yanqu.road.server.manger.activity;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.UnionActivityConditionData;
import com.yanqu.road.entity.activity.UserActivityConditionData;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.enums.eBigRankType;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.entity.rank.UserRank;
import com.yanqu.road.entity.union.UnionBaseInfo;
import com.yanqu.road.logic.bussiness.player.UserActivityBussiness;
import com.yanqu.road.logic.bussiness.player.UserRelationActivityBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.logic.pb.UnionBasePb;
import com.yanqu.road.logic.rank.RankListModel;
import com.yanqu.road.logic.rank.UnionActivityRankListModel;
import com.yanqu.road.pb.crossunion.activity.CrossUnionActivityRankDataProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.manger.cross.CrossDataMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.rank.RankMgr;
import com.yanqu.road.server.manger.union.UnionActivityMgr;
import com.yanqu.road.server.manger.union.CrossUnionMgr;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class RelationActivityRankMgr extends TempMgr {

    private static Map<Integer, RankListModel> rankListModelMap;

    private static Map<Integer, UnionActivityRankListModel> unionRankListModelMap;

    private static Map<Integer, RankListModel> serverRankListModelMap;

    private static Map<Integer, Map<Long, UserActivityConditionData>> unionUserActivityDataMap;

    private static Map<Integer, Map<String, UnionActivityConditionData>> unionConditionDataMap;

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean stop() {
        return false;
    }

    @Override
    public boolean save() {
        for (Map<String, UnionActivityConditionData> unionActivityConditionDataMap : unionConditionDataMap.values()) {
            for (UnionActivityConditionData data : unionActivityConditionDataMap.values()) {
                if (data.isInsertOption()) {
                    UserActivityBussiness.addUnionActivityConditionData(data);
                } else if (data.isUpdateOption()) {
                    UserActivityBussiness.updateUnionActivityConditionData(data);
                }
            }
        }
        return true;
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        rankListModelMap = new ConcurrentHashMap<>();
        unionRankListModelMap = new ConcurrentHashMap<>();
        unionConditionDataMap = new ConcurrentHashMap<>();
        unionUserActivityDataMap = new ConcurrentHashMap<>();
        reloadRank();
        return true;
    }

    public static RankListModel getRankListModel(int activityId) {
        return rankListModelMap.get(activityId);
    }

    public static UnionActivityRankListModel getUnionRankListModel(int activityId){
        return unionRankListModelMap.get(activityId);
    }

    public static void removeUnionActivityRank(int activityId, String unionUid){
        UnionActivityRankListModel unionActivityRankListModel = getUnionActivityRankListModel(activityId);
        if(null != unionActivityRankListModel){
            unionActivityRankListModel.removeRank(unionUid);
        }
    }

    public static int getActivityRank(int activityId, long userId) {
        RankListModel rankListModel = getRankListModel(activityId);
        if (null != rankListModel) {
            return rankListModel.getMyRank(userId);
        }
        return -1;
    }

    public static int getActivityUnionRank(int activityId, String unionUid){
        UnionActivityRankListModel rankListModel = getUnionRankListModel(activityId);
        if(null != rankListModel){
            return rankListModel.getMyRank(unionUid);
        }
        return -1;
    }

    public static void changeRank(int activityId, UserInfo userInfo, BigInteger value) {
        ActivityInfo activityInfo = RelationActivityMgr.getOpenActivityInfo(activityId);
        RankListModel rankListModel = getRankListModel(activityId);
        if (null != rankListModel) {
            UserRank userRank = rankListModel.rankChange(userInfo.getUserId(), UserMgr.parseUserBaseInfo(userInfo, GameServer.getInstance().getServerId()), value, "");
            // 是小当家活动就发上去
            if(null != userRank && null != activityInfo && (activityInfo.getType() == eActivityType.CookingBoyActivity.getValue() || activityInfo.getType() == eActivityType.ChefDuel.getValue())){
                //跨服活动排行变更，排名前100名上榜
                CrossDataMgr.relationRankChange(activityId, userRank);
            }
        }
    }

    public static void changeUserInfo(long userId) {
        UserInfo userInfo = UserMgr.getUserInfo(userId);
        if(null == userInfo){
            return;
        }
        //管理员账号不参与排行
        if (userInfo.isAdmin()) {
            return;
        }
        for (RankListModel model : rankListModelMap.values()) {
            model.changeUserInfo(userId, UserMgr.parseUserBaseInfo(userInfo, GameServer.getInstance().getServerId()));
        }
    }

    /**
     * 加载活动排行榜
     */
    public static void reloadRank() {
        List<ActivityInfo> activityInfoList = RelationActivityMgr.getOpenActivityInfoList();
        for(ActivityInfo activityInfo : activityInfoList){
            //个人榜
            int rankNum;
            if(!rankListModelMap.containsKey(activityInfo.getActivityId())) {
                RankListModel rankListModel = new RankListModel(eBigRankType.Normal.getValue(),activityInfo.getActivityId());
                int rankUserType = RelationActivityMgr.getRankEvent(activityInfo.getActivityId(),RelationActivityMgr.EVENT_RANK_USER_TYPE);
                rankNum = RelationActivityMgr.getMaxRankByType(activityInfo.getActivityId(), rankUserType);
                if (rankNum <= 0) {
                    rankNum = GameConfig.RANK_DEFAULT_MAX_COUNT;
                }
                rankListModel.setRankNum(rankNum);
                List<UserActivityConditionData> uadList = UserRelationActivityBussiness.getUserActivityConditionDataList(activityInfo.getActivityId(),
                        rankUserType, rankNum);
                List<UserActivityConditionData> noZeroList = new ArrayList<>();
                for(UserActivityConditionData uad : uadList){
                    if(uad.getValue().compareTo(BigInteger.ZERO) > 0){
                        noZeroList.add(uad);
                    }
                }
                rankListModel.setRankList(RankMgr.parseUserRankList(noZeroList, rankNum));
                rankListModelMap.put(activityInfo.getActivityId(), rankListModel);
            }
            //商会榜
            if(!unionRankListModelMap.containsKey(activityInfo.getActivityId())) {
                int rankUnionType = RelationActivityMgr.getRankEvent(activityInfo.getActivityId(),RelationActivityMgr.EVENT_RANK_UNION_TYPE);
                Map<Long, UserActivityConditionData> tempUserConditionDataMap = UserRelationActivityBussiness.getUserActivityConditionDataMap(activityInfo.getActivityId(),
                        rankUnionType);
                Map<String, UnionActivityConditionData> tempUnionConditionDataMap = UserActivityBussiness.getUnionActivityConditionDataMap(activityInfo.getActivityId());
                Map<String, UnionActivityConditionData> rankUnionConditionDataMap = new ConcurrentHashMap<>();
                for(String unionUid : tempUnionConditionDataMap.keySet()){
                    if(tempUnionConditionDataMap.get(unionUid).getValue().compareTo(BigInteger.ZERO) > 0){
                        rankUnionConditionDataMap.put(unionUid,tempUnionConditionDataMap.get(unionUid));
                    }
                }
                UnionActivityMgr.checkUnionActivityConditionData(tempUserConditionDataMap, tempUnionConditionDataMap);
                unionConditionDataMap.put(activityInfo.getActivityId(), tempUnionConditionDataMap);
                unionUserActivityDataMap.put(activityInfo.getActivityId(), tempUserConditionDataMap);
                UnionActivityRankListModel unionRankListModel = new UnionActivityRankListModel(activityInfo.getActivityId());
                rankNum = RelationActivityMgr.getMaxRankByType(activityInfo.getActivityId(), rankUnionType);
                if (rankNum <= 0) {
                    rankNum = GameConfig.RANK_DEFAULT_MAX_COUNT;
                }
                unionRankListModel.setRankNum(rankNum);
                unionRankListModel.initRankList(rankUnionConditionDataMap);
                unionRankListModelMap.put(activityInfo.getActivityId(), unionRankListModel);
            }
        }
    }

    public static void changeUnionActivityValue(int activityId, String unionUid, long userId, UserActivityConditionData userConditionData, int notifyType) {
   /*     UnionInfo unionInfo = CrossUnionMgr.getUnionInfo(unionUid);
        if (null != unionInfo) {*/
            ActivityInfo activityInfo = RelationActivityMgr.getOpenActivityInfo(activityId);
            //属于活动开始和结束时间
            if (null != activityInfo && activityId == activityInfo.getActivityId()) {
                long beginTime = activityInfo.getBeginTime();
                long endTime = activityInfo.getEndTime();
                long now = System.currentTimeMillis() / 1000;
                if (now < beginTime || now > endTime + 120) {
                    return;
                }
              /*  checkUnionConditionData(activityId, unionUid);
                UnionActivityConditionData unionActivityConditionData;
                synchronized (unionConditionDataMap) {
                    unionActivityConditionData = UnionActivityMgr.changeUnionActivityConditionData(activityId, unionUid, unionInfo, unionConditionDataMap);
                    if(UnionRiseRankArgs.NOTIFY_TYPE_NORMAL == notifyType){
                        if(null != userConditionData) {
                            unionActivityConditionData.addMemberUserId(userConditionData.getUserId());
                            setUserActivityConditionData(userConditionData);
                            UnionActivityMgr.changeUnionMemberPositionData(unionUid,userId,unionActivityConditionData);
                        }
                        //出bug了，临时加一个触发校验商会成员的
                        if(unionActivityConditionData.getMemberUserCount() != CrossUnionMgr.getUnionMemberCount(unionUid)){
                            List<Long> memberUserIdList = new ArrayList<>(unionActivityConditionData.getMemberUserIdList());
                            for (long memberUserId : memberUserIdList) {
                                UnionMember unionMember = CrossUnionMgr.getUnionMember(unionUid,memberUserId);
                                if(unionMember == null){
                                    unionActivityConditionData.removeMemberUserId(memberUserId);
                                    unionActivityConditionData.removeMemberPosition(memberUserId);
                                }
                            }
                        }
                    }else if(UnionRiseRankArgs.NOTIFY_TYPE_JOIN == notifyType && !ActivityMgr.activityOverEndTime(activityInfo)){
                        if(null != userConditionData) {
                            unionActivityConditionData.addMemberUserId(userConditionData.getUserId());
                            setUserActivityConditionData(userConditionData);
                        }
                    }else if((UnionRiseRankArgs.NOTIFY_TYPE_REMOVE == notifyType || UnionRiseRankArgs.NOTIFY_TYPE_DELETE == notifyType) &&
                            !ActivityMgr.activityOverEndTime(activityInfo)){
                        unionActivityConditionData.removeMemberUserId(userId);
                        unionActivityConditionData.removeMemberPosition(userId);
                    }else if(UnionRiseRankArgs.NOTIFY_TYPE_POSITION_CHANGE == notifyType){
                        UnionActivityMgr.changeUnionMemberPositionData(unionUid,userId,unionActivityConditionData);
                    }
                    UnionActivityMgr.calcUnionActivityConditionValue(unionActivityConditionData, getUserActivityConditionDataMap(activityId));
                }
                UnionActivityRankListModel unionActivityRankListModel = getUnionActivityRankListModel(activityId);
                if(null != unionActivityRankListModel) {
                    //waring waring waring 这里大于0才上榜且没有负数
                    if(unionActivityConditionData.getMemberUserCount() > 0 && unionActivityConditionData.getValue().compareTo(BigInteger.ZERO) > 0) {
                        UnionActivityRank unionRank = unionActivityRankListModel.rankChange(unionActivityConditionData);
                        if(null != unionRank && activityInfo.getType() == eActivityType.CookingBoyActivity.getValue()){
                          //  CrossDataMgr.relationUnionRankChange(activityId, unionRank,false);
                        }
                    }else {
                        UnionActivityRank unionRank = unionActivityRankListModel.rankChange(unionActivityConditionData);
                        unionActivityRankListModel.removeRank(unionUid);
                      //  CrossDataMgr.relationUnionRankChange(activityId, unionRank,true);
                    }
                }
*/
                if (userConditionData == null) {
                    return;
                }

                CrossUnionActivityRankDataProto.CrossUnionActivityUserDataMsg.Builder msg = CrossUnionActivityRankDataProto.CrossUnionActivityUserDataMsg.newBuilder();
                msg.setActivityId(activityId);
                msg.setConditionType(userConditionData.getType());
                msg.setUserId(userId);
                msg.setValue(userConditionData.getValue().toString());
                msg.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(UserMgr.getUserBaseInfo(userId, GameServer.getInstance().getServerId())));
                msg.setUnionId(unionUid);
                msg.setChangeType(notifyType);
                Map<Long, Integer> positionMap = CrossUnionMgr.getMemberPositionMap(unionUid);
                for (Map.Entry<Long, Integer> entry : positionMap.entrySet()) {
                    Long memberId = entry.getKey();
                    Integer pos = entry.getValue();
                    CrossUnionActivityRankDataProto.CrossUnionMemberPosDataMsg.Builder builder = CrossUnionActivityRankDataProto.CrossUnionMemberPosDataMsg.newBuilder();
                    builder.setPos(pos);
                    builder.setUserId(memberId);
                    msg.addMember(builder);
                }
                msg.setUnionServerId(CrossUnionMgr.getUnionServerId(unionUid));
                UnionBaseInfo unionBaseInfo = CrossUnionMgr.parseUnionBaseInfo(unionUid);
                if (unionBaseInfo != null) {
                    msg.setUnionBaseInfo(UnionBasePb.parseUnionBaseTempMsg(unionBaseInfo));
                }
                if (!CrossUnionMgr.isAllSync()) {
                    return;
                }
                YanQuMessage message = YanQuMessageUtils.buildMessage(CrossProtocol.C_CROSS_UNION_ACTIVITY_USER_VALUE_CHANGE, msg);
                GamePlayerMgr.sendPacket(0, message);
            }
     //   }
    }


    public static void changeUnionActivityValue(int activityId, String unionUid, int conditionType, int notifyType) {
        ActivityInfo activityInfo = RelationActivityMgr.getOpenActivityInfo(activityId);
        //属于活动开始和结束时间
        if (null != activityInfo && activityId == activityInfo.getActivityId()) {
            long beginTime = activityInfo.getBeginTime();
            long endTime = activityInfo.getEndTime();
            long now = System.currentTimeMillis() / 1000;
            if (now < beginTime || now > endTime + 120) {
                return;
            }

            CrossUnionActivityRankDataProto.CrossUnionActivityUserDataMsg.Builder msg = CrossUnionActivityRankDataProto.CrossUnionActivityUserDataMsg.newBuilder();
            msg.setActivityId(activityId);
            msg.setConditionType(conditionType);
            msg.setUserId(0);
            msg.setValue("0");
            msg.setUnionId(unionUid);
            msg.setChangeType(notifyType);
            Map<Long, Integer> positionMap = CrossUnionMgr.getMemberPositionMap(unionUid);
            for (Map.Entry<Long, Integer> entry : positionMap.entrySet()) {
                Long memberId = entry.getKey();
                Integer pos = entry.getValue();
                CrossUnionActivityRankDataProto.CrossUnionMemberPosDataMsg.Builder builder = CrossUnionActivityRankDataProto.CrossUnionMemberPosDataMsg.newBuilder();
                builder.setPos(pos);
                builder.setUserId(memberId);
                msg.addMember(builder);
            }
            msg.setUnionServerId(CrossUnionMgr.getUnionServerId(unionUid));
            UnionBaseInfo unionBaseInfo = CrossUnionMgr.parseUnionBaseInfo(unionUid);
            if (unionBaseInfo != null) {
                msg.setUnionBaseInfo(UnionBasePb.parseUnionBaseTempMsg(unionBaseInfo));
            }
            if (!CrossUnionMgr.isAllSync()) {
                return;
            }
            YanQuMessage message = YanQuMessageUtils.buildMessage(CrossProtocol.C_CROSS_UNION_ACTIVITY_USER_VALUE_CHANGE, msg);
            GamePlayerMgr.sendPacket(0, message);
        }
        //   }
    }

    public static UnionActivityRankListModel getUnionActivityRankListModel(Integer activityId) {
        return unionRankListModelMap.get(activityId);
    }

    public static Map<Long, UserActivityConditionData> getUserActivityConditionDataMap(int activityId){
        return unionUserActivityDataMap.get(activityId);
    }

    public static UserActivityConditionData getUserActivityConditionData(int activityId, long userId){
        Map<Long, UserActivityConditionData> dataMap = getUserActivityConditionDataMap(activityId);
        if(null != dataMap){
            return dataMap.get(userId);
        }
        return null;
    }

    public static void setUserActivityConditionData(UserActivityConditionData userActivityConditionData){
        if(null == userActivityConditionData){
            return;
        }
        checkUnionUserConditionData(userActivityConditionData.getActivityId());
        Map<Long, UserActivityConditionData> dataMap = getUserActivityConditionDataMap(userActivityConditionData.getActivityId());
        if(null != dataMap){
            dataMap.put(userActivityConditionData.getUserId(), userActivityConditionData);
        }
    }

    public static UnionActivityConditionData getUnionActivityConditionData(int activityId, String unionUid){
        Map<String, UnionActivityConditionData> dataMap = getUnionActivityConditionDataMap(activityId);
        if(null != dataMap){
            return dataMap.get(unionUid);
        }
        return null;
    }

    public static Map<String, UnionActivityConditionData> getUnionActivityConditionDataMap(int activityId){
        return unionConditionDataMap.get(activityId);
    }

    public static UnionActivityConditionData getUnionActivityConditionData(int activityId, long userId){
        Map<String, UnionActivityConditionData> dataMap = getUnionActivityConditionDataMap(activityId);
        if(null != dataMap){
            for(UnionActivityConditionData unionActivityConditionData : dataMap.values()){
                if(unionActivityConditionData.hasMemberUserId(userId)){
                    return unionActivityConditionData;
                }
            }
        }
        return null;
    }

    private static void checkUnionUserConditionData(int activityId){
        if(!unionUserActivityDataMap.containsKey(activityId)){
            synchronized (unionUserActivityDataMap){
                if(!unionUserActivityDataMap.containsKey(activityId)){
                    unionUserActivityDataMap.put(activityId, new ConcurrentHashMap<>());
                }
            }
        }
    }

    private static void checkUnionConditionData(int activityId, String unionUid){
        if (!StringUtils.isNullOrEmpty(unionUid)) {
            if (!unionConditionDataMap.containsKey(activityId)) {
                synchronized (unionConditionDataMap) {
                    if (!unionConditionDataMap.containsKey(activityId)) {
                        unionConditionDataMap.put(activityId, new ConcurrentHashMap<>());
                    }
                }
            }
        }
    }
}
